var __awaiter = (this && this.__awaiter) || function(thisArg, _arguments, P, generator) {
	function adopt(value) {
		return value instanceof P ? value : new P(function(resolve) {
			resolve(value);
		});
	}
	return new(P || (P = Promise))(function(resolve, reject) {
		function fulfilled(value) {
			try {
				step(generator.next(value));
			} catch (e) {
				reject(e);
			}
		}

		function rejected(value) {
			try {
				step(generator["throw"](value));
			} catch (e) {
				reject(e);
			}
		}

		function step(result) {
			result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
		}
		step((generator = generator.apply(thisArg, _arguments || [])).next());
	});
};
import {
	NAME
} from './constants';
import {
	TRTCRoleType,
	TRTCAudioQuality,
	TRTCVideoRotation,
	TRTCVideoFillMode,
	TRTCVideoMirrorType,
	TRTCVideoStreamType,
	TRTCVideoEncParam,
	TRTCAppScene,
	TRTCAudioRoute,
	TRTCBeautyStyle,
} from './TrtcDefines';
import TrtcError, {
	TXLiteJSError,
	generateError_
} from './TrtcCode';
const TrtcNativeTrtcCloudModule = uni.requireNativePlugin('TRTCCloudUniPlugin-TRTCCloudImpl');
const TXAudioEffectManagerModule = uni.requireNativePlugin(
	'TRTCCloudUniPlugin-TRTCCloudImpl-TXAudioEffectManagerModule');
const TrtcEvent = uni.requireNativePlugin('globalEvent');
let trtcCloud = null; // trtcCloud 单例
export default class TrtcCloudImpl {
	constructor() {
		this.listenersMap_ = new Map();
	}
	static _createInstance() {
		try {
			if (trtcCloud) {
				return trtcCloud;
			}
			TrtcNativeTrtcCloudModule.sharedInstance();
			trtcCloud = new TrtcCloudImpl();
			return trtcCloud;
		} catch (error) {
			throw generateError_(error);
		}
	}
	static _getInstance() {
		if (trtcCloud) {
			return trtcCloud;
		}
		throw new TrtcError({
			code: TXLiteJSError.INVALID_OPERATION,
			message: 'get trtcCloud failed, please create trtcCloud first',
		});
	}
	static _destroyInstance() {
		try {
			trtcCloud = null;
			TrtcNativeTrtcCloudModule.destroySharedInstance();
		} catch (error) {
			throw new TrtcError({
				code: error.code || TXLiteJSError.UNKNOWN,
				message: error.message,
				name: error.name,
			});
		}
	}
	// 截图保存
	// async saveImage_(base64Data) {
	//   return new Promise((resolve, reject) => {
	//     let bitmap = new plus.nativeObj.Bitmap();
	//     bitmap.loadBase64Data(base64Data, () => {
	//       const url = "_doc/" + new Date().getTime() + ".png";  // url为时间戳命名方式
	//       console.log('saveHeadImgFile', url);
	//       bitmap.save(url, { overwrite: true }, (i) => {
	//         uni.saveImageToPhotosAlbum({
	//           filePath: url,
	//           success: function() {
	//             uni.showToast({
	//               title: '图片保存成功',
	//               icon: 'none'
	//             })
	//             bitmap.clear();
	//             resolve({ code: 0, message: '图片保存成功' });
	//           }
	//         });
	//       }, (e) => {
	//         uni.showToast({
	//           title: '图片保存失败, 请重新截图',
	//           icon: 'none'
	//         })
	//         bitmap.clear();
	//         resolve({ code: -1, message: '图片保存失败, 请重新截图' });
	//       });
	//     });
	//   });
	// }
	on(event, callback) {
		if (typeof event !== NAME.STRING || typeof callback !== NAME.FUNCTION) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the on method parameter types. event type is a ${typeof event}; callback type is a ${typeof callback}`,
			});
		}
		const nativeListener = (res) => __awaiter(this, void 0, void 0, function*() {
			const {
				data = []
			} = res;
			const code = data[0];
			const message = data[1] || '';
			const extraInfo = data[2] || {};
			switch (event) {
				case 'onEnterRoom': {
					const result = code;
					callback(result);
					break;
				}
				case 'onExitRoom': {
					const reason = code;
					callback(reason);
					break;
				}
				case 'onFirstVideoFrame': {
					const userId = code;
					const streamType = data[1] || 0;
					const width = data[2] || 0;
					const height = data[3] || 0;
					callback({
						userId,
						streamType,
						width,
						height
					});
					break;
				}
				case 'onFirstAudioFrame': {
					const userId = code || '';
					callback(userId);
					break;
				}
				case 'onMicDidReady': {
					callback();
					break;
				}
				case 'onCameraDidReady': {
					callback();
					break;
				}
				case 'onNetworkQuality': {
					const localQuality = data[0];
					const remoteQuality = data[1];
					callback({
						localQuality,
						remoteQuality
					});
					break;
				}
				case 'onRemoteUserEnterRoom': {
					const userId = code || '';
					callback(userId);
					break;
				}
				case 'onRemoteUserLeaveRoom': {
					const userId = code || '';
					const reason = message;
					callback({
						userId,
						reason
					});
					break;
				}
				case 'onSendFirstLocalAudioFrame': {
					callback();
					break;
				}
				case 'onSendFirstLocalVideoFrame': {
					const streamType = code;
					callback(streamType);
					break;
				}
				case 'onStatistics': {
					const statics = data[0] || {};
					callback(statics);
					break;
				}
				case 'onUserAudioAvailable': {
					const userId = code || '';
					const available = message;
					callback({
						userId,
						available
					});
					break;
				}
				case 'onUserVideoAvailable': {
					const userId = code || '';
					const available = message;
					callback({
						userId,
						available
					});
					break;
				}
				case 'onUserVoiceVolume': {
					const userVolumes = data[0];
					const totalVolume = data[1];
					callback({
						userVolumes,
						totalVolume
					});
					break;
				}
				case 'onSwitchRole': {
					callback({
						code,
						message
					});
					break;
				}
				case 'onScreenCaptureStarted': {
					callback({
						code,
						message
					});
					break;
				}
				case 'onScreenCapturePaused': {
					callback({
						code,
						message
					});
					break;
				}
				case 'onScreenCaptureResumed': {
					callback({
						code,
						message
					});
					break;
				}
				case 'onScreenCaptureStopped': {
					callback({
						code,
						message
					});
					break;
				}
				case 'onUserSubStreamAvailable': {
					const userId = code || '';
					const available = message;
					callback({
						userId,
						available
					});
					break;
				}
				case 'onSnapshotComplete': {
					// base64 直接保存到本地图库
					// const { code: snapShotCode, message: msg } = await this.saveImage_(code);
					// callback({ snapShotCode, message: msg });
					callback({
						base64Data: code,
						message
					});
					break;
				}
				case 'onUserVideoSizeChanged': {
					callback(data);
					break;
				}
				case 'onStart': {
					callback({
						id: code,
						errCode: message
					});
					break;
				}
				case 'onPlayProgress': {
					callback({
						id: code,
						curPtsMS: message,
						durationMS: extraInfo
					});
					break;
				}
				case 'onComplete': {
					callback({
						id: code,
						errCode: message
					});
					break;
				}
				case 'onError': {
					console.error(`onError: ${code}, ${message}, ${extraInfo}`);
					callback(generateError_({
						message
					}, code, extraInfo));
					break;
				}
				default: {
					callback({
						code,
						message,
						extraInfo
					});
				}
			}
		});
		this.listenersMap_.set(event, nativeListener); // 多次设置同一个事件时，后面的 callback 覆盖前面
		TrtcEvent.addEventListener(event, nativeListener);
	}
	off(event) {
		if (typeof event !== NAME.STRING) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the off method parameter types. event type is a ${typeof event} not a ${NAME.STRING}`,
			});
		}
		try {
			if (event === '*') {
				this.listenersMap_.forEach((value, key) => {
					TrtcEvent.removeEventListener(key, value);
				});
				this.listenersMap_.clear();
			} else {
				TrtcEvent.removeEventListener(event, this.listenersMap_.get(event));
				this.listenersMap_.delete(event);
			}
		} catch (error) {
			throw generateError_(error);
		}
	}
	enterRoom(params, scene) {
		if (scene !== TRTCAppScene.TRTCAppSceneVideoCall && scene !== TRTCAppScene.TRTCAppSceneLIVE && scene !==
			TRTCAppScene.TRTCAppSceneAudioCall && scene !== TRTCAppScene.TRTCAppSceneVoiceChatRoom) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the enterRoom method parameters. scene is not of TRTCAppScene`,
			});
		}
		try {
			const enterRoomParams = Object.assign(Object.assign({}, params), {
				role: params.role || TRTCRoleType.TRTCRoleAnchor,
				appScene: scene
			});
			TrtcNativeTrtcCloudModule.enterRoom(enterRoomParams);
		} catch (error) {
			throw generateError_(error);
		}
	}
	exitRoom() {
		try {
			TrtcNativeTrtcCloudModule.exitRoom();
		} catch (error) {
			throw generateError_(error);
		}
	}
	switchRole(role) {
		if (role !== TRTCRoleType.TRTCRoleAnchor && role !== TRTCRoleType.TRTCRoleAudience) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the switchRole method parameter. role is not of TRTCRoleType`,
			});
		}
		try {
			role && TrtcNativeTrtcCloudModule.switchRole(role);
		} catch (error) {
			throw generateError_(error);
		}
	}
	startLocalPreview(isFrontCamera = true, viewId) {
		if (typeof isFrontCamera !== NAME.BOOLEAN || !viewId || typeof viewId !== NAME.STRING) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the startLocalPreview method parameters`,
			});
		}
		try {
			let param = {
				isFrontCamera: !!isFrontCamera
			};
			param = viewId ? Object.assign(Object.assign({}, param), {
				userId: viewId
			}) : param;
			TrtcNativeTrtcCloudModule.startLocalPreview(param);
		} catch (error) {
			throw generateError_(error);
		}
	}
	setVideoEncoderParam(param) {
		try {
			TrtcNativeTrtcCloudModule.setVideoEncoderParam(param);
		} catch (error) {
			throw generateError_(error);
		}
	}
	stopLocalPreview() {
		try {
			TrtcNativeTrtcCloudModule.stopLocalPreview();
		} catch (error) {
			throw generateError_(error);
		}
	}
	switchCamera(isFrontCamera) {
		if (typeof isFrontCamera !== NAME.BOOLEAN) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the switchCamera method parameter`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.switchCamera(isFrontCamera);
		} catch (error) {
			throw generateError_(error);
		}
	}
	setLocalRenderParams(params) {
		try {
			const {
				rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode
					.TRTCVideoFillMode_Fill, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
			} = params;
			TrtcNativeTrtcCloudModule.setLocalRenderParams({
				rotation,
				fillMode,
				mirrorType,
			});
		} catch (error) {
			throw generateError_(error);
		}
	}
	muteLocalVideo(streamType, mute) {
		if (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType
			.TRTCVideoStreamTypeSub || typeof mute !== NAME.BOOLEAN) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the muteLocalVideo method parameters`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.muteLocalVideo({
				streamType,
				mute: !!mute
			});
		} catch (error) {
			throw generateError_(error);
		}
	}
	startRemoteView(userId, streamType, viewId) {
		if (!userId || streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !==
			TRTCVideoStreamType.TRTCVideoStreamTypeSmall && streamType !== TRTCVideoStreamType
			.TRTCVideoStreamTypeSub || !viewId) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the startRemoteView method parameters`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.startRemoteView({
				userId,
				streamType,
				viewId
			});
		} catch (error) {
			throw generateError_(error);
		}
	}
	stopRemoteView(userId, streamType) {
		if (!userId || streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !==
			TRTCVideoStreamType.TRTCVideoStreamTypeSmall && streamType !== TRTCVideoStreamType
			.TRTCVideoStreamTypeSub) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the stopRemoteView method parameters`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.stopRemoteView({
				userId,
				streamType
			});
		} catch (error) {
			throw generateError_(error);
		}
	}
	// 远端渲染设置
	setRemoteRenderParams(userId, streamType, params) {
		try {
			if (!userId || (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !==
					TRTCVideoStreamType.TRTCVideoStreamTypeSub)) {
				throw new TrtcError({
					code: TXLiteJSError.INVALID_PARAMETER,
					message: `${NAME.LOG_PREFIX} please check the snapshotVideo method parameters`,
				});
			}
			const {
				rotation = TRTCVideoRotation.TRTCVideoRotation_0, fillMode = TRTCVideoFillMode
					.TRTCVideoFillMode_Fill, mirrorType = TRTCVideoMirrorType.TRTCVideoMirrorType_Auto
			} = params;
			TrtcNativeTrtcCloudModule.setRemoteRenderParams({
				userId,
				streamType,
				rotation,
				fillMode,
				mirrorType
			});
		} catch (error) {
			throw generateError_(error);
		}
	}
	// 截图
	snapshotVideo(userId, streamType) {
		if (streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeBig && streamType !== TRTCVideoStreamType
			.TRTCVideoStreamTypeSub) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the snapshotVideo method parameters`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.snapshotVideo({
				userId: userId || null,
				streamType
			});
		} catch (error) {
			throw generateError_(error);
		}
	}
	startLocalAudio(quality = TRTCAudioQuality.TRTCAudioQualityDefault) {
		if (quality !== TRTCAudioQuality.TRTCAudioQualitySpeech && quality !== TRTCAudioQuality
			.TRTCAudioQualityDefault && quality !== TRTCAudioQuality.TRTCAudioQualityMusic) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the startLocalAudio method parameters`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.startLocalAudio(quality);
		} catch (error) {
			throw generateError_(error);
		}
	}
	stopLocalAudio() {
		try {
			TrtcNativeTrtcCloudModule.stopLocalAudio();
		} catch (error) {
			throw generateError_(error);
		}
	}
	muteLocalAudio(mute) {
		if (typeof mute !== NAME.BOOLEAN) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the muteLocalAudio method parameters, mute type is a ${typeof mute} not a ${NAME.BOOLEAN}`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.muteLocalAudio(!!mute);
		} catch (error) {
			throw generateError_(error);
		}
	}
	muteRemoteAudio(userId, mute) {
		if (typeof mute !== NAME.BOOLEAN || !userId) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the muteRemoteAudio method parameters`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.muteRemoteAudio({
				userId,
				mute: !!mute
			});
		} catch (error) {
			throw generateError_(error);
		}
	}
	muteAllRemoteAudio(mute) {
		if (typeof mute !== NAME.BOOLEAN) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the muteAllRemoteAudio method parameters, mute type is a ${typeof mute} not a ${NAME.BOOLEAN}`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.muteAllRemoteAudio(!!mute);
		} catch (error) {
			throw generateError_(error);
		}
	}
	setAudioRoute(route) {
		if (route !== TRTCAudioRoute.TRTCAudioRouteSpeaker && route !== TRTCAudioRoute.TRTCAudioRouteEarpiece) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the setAudioRoute method parameter, route is not of TRTCAudioRoute`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.setAudioRoute(route);
		} catch (error) {
			throw generateError_(error);
		}
	}
	enableAudioVolumeEvaluation(interval) {
		if (typeof interval !== NAME.NUMBER) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the enableAudioVolumeEvaluation method parameter, interval type is a ${typeof interval} not a ${NAME.NUMBER}`,
			});
		}
		try {
			interval > 0 && TrtcNativeTrtcCloudModule.enableAudioVolumeEvaluation(interval);
		} catch (error) {
			throw generateError_(error);
		}
	}
	// ///////////////////////////////////////////////////////////////////////////////
	//
	//                      美颜 + 水印
	//
	// ///////////////////////////////////////////////////////////////////////////////
	setBeautyStyle(beautyStyle) {
		if (beautyStyle !== TRTCBeautyStyle.TRTCBeautyStyleSmooth && beautyStyle !== TRTCBeautyStyle
			.TRTCBeautyStyleNature && beautyStyle !== TRTCBeautyStyle.TRTCBeautyStylePitu) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the setBeautyStyle method parameter, beautyStyle is not of TRTCBeautyStyle`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.setBeautyStyle(beautyStyle);
		} catch (error) {
			throw generateError_(error);
		}
	}
	setBeautyLevel(beautyLevel) {
		if (typeof beautyLevel !== NAME.NUMBER || (beautyLevel < 0 || beautyLevel > 9)) {
			throw new TrtcError({
				code: TXLiteJSError.INVALID_PARAMETER,
				message: `${NAME.LOG_PREFIX} please check the setBeautyLevel method parameter, beautyLevel should in the range 0-9`,
			});
		}
		try {
			TrtcNativeTrtcCloudModule.setBeautyLevel(beautyLevel);
		} catch (error) {
			throw generateError_(error);
		}
	}
	// ///////////////////////////////////////////////////////////////////////////////
	//
	//                      背景音效
	//
	// ///////////////////////////////////////////////////////////////////////////////
	startPlayMusic(musicParam) {
		try {
			TXAudioEffectManagerModule.startPlayMusic(musicParam);
		} catch (error) {
			throw generateError_(error);
		}
	}
	stopPlayMusic(id) {
		try {
			TXAudioEffectManagerModule.stopPlayMusic(id);
		} catch (error) {
			throw generateError_(error);
		}
	}
	pausePlayMusic(id) {
		try {
			TXAudioEffectManagerModule.pausePlayMusic(id);
		} catch (error) {
			throw generateError_(error);
		}
	}
	resumePlayMusic(id) {
		try {
			TXAudioEffectManagerModule.resumePlayMusic(id);
		} catch (error) {
			throw generateError_(error);
		}
	}
	// ///////////////////////////////////////////////////////////////////////////////
	//
	//                      屏幕分享
	//
	// ///////////////////////////////////////////////////////////////////////////////
	setSubStreamEncoderParam(param) {
		try {
			TrtcNativeTrtcCloudModule.setSubStreamEncoderParam(param);
		} catch (error) {
			throw generateError_(error);
		}
	}
	startScreenCapture(streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub, encParams = null) {
		try {
			let platform = uni.getSystemInfoSync().platform;
			if ((streamType !== TRTCVideoStreamType.TRTCVideoStreamTypeSub && streamType !== TRTCVideoStreamType
					.TRTCVideoStreamTypeBig)) {
				streamType = TRTCVideoStreamType.TRTCVideoStreamTypeSub;
			}
			const screenCaptureParams = Object.assign({
				streamType
			}, encParams);
			if (platform === NAME.ANDROID) {
				TrtcNativeTrtcCloudModule.startScreenCapture(screenCaptureParams);
			}
			if (platform === NAME.IOS) {
				// 开始应用内的屏幕分享（仅支持 iOS 13.0 及以上系统）
				TrtcNativeTrtcCloudModule.startScreenCaptureInApp(screenCaptureParams);
				// if (shareSource === TRTCShareSource.InApp) {
				//   TrtcNativeTrtcCloudModule.startScreenCaptureInApp(screenCaptureParams);
				// }
				// // 开始全系统的屏幕分享（仅支持 iOS 11.0 及以上系统）
				// if (shareSource === TRTCShareSource.ByReplaykit) {
				//   TrtcNativeTrtcCloudModule.startScreenCaptureByReplaykit({ ...screenCaptureParams, appGroup: null });
				// }
			}
		} catch (error) {
			throw generateError_(error);
		}
	}
	stopScreenCapture() {
		try {
			TrtcNativeTrtcCloudModule.stopScreenCapture();
		} catch (error) {
			throw generateError_(error);
		}
	}
	pauseScreenCapture() {
		try {
			TrtcNativeTrtcCloudModule.pauseScreenCapture();
		} catch (error) {
			throw generateError_(error);
		}
	}
	resumeScreenCapture() {
		try {
			TrtcNativeTrtcCloudModule.resumeScreenCapture();
		} catch (error) {
			throw generateError_(error);
		}
	}
}